Ana içeriğe geç

Match Yapıları

Match yapıları türkçeye çevirisi ile eşleştirme yapıları adının üstünde bir değeri belirli değer havuzundaki değerler ile eşleştirmeye ve bu eşleştirme sonucunda istenilen kodu çalıştırmaya yarayacaktır. Bu işlemi üst kısımda evcil_hayvanları sınıflandırırken gerçekleştirdik. Aslında match sistemleri tam olarak da bu şekildeki durumlarda çalışmaktadır.

Hadi örnekler ile bunu inceleyelim:

fn bir_ekle(x: Option<i32>)-> Option<i32>{
match x {
None => None,
Some(i) => Some(i + 1),
}
}

Match yapımızı kurduk. İçerisine Option<i32> alıyor ve çıktı olarak Option<i32> değeri veriyor. Sonrasında iç kısmına baktığımızda eğer veri None yani boşsa boş değeri eğer doluysa bu değerin bir fazlasını döndürüyor. Sonrasında yazdığımız bu kodu deneyebiliriz:

fn main(){
let five = Some(5);
let six = bir_ekle(five);
let none = bir_ekle(None);
}

Şimdi bu koda baktık ve tamam da ne işimize yarayacak diye düşünebilirsiniz. Bu işlemler aslında kodumuza girilebilecek hiçlik değerlerine karşı bizi koruyor. Mesala kullanıcı bir form dolduruyor ve Telefon numarasını doldurmadan atladı. Artık telefon numarasının değeri yok. Bu şekilde bir kod yapısı ile None değeri için bir match yapısı yazmazsak kodumuz bilinmez haraket yani unknown behevior yapacak ve güvensiz olacaktır. Aslında biz tam olarak da bunu engellemek için None değeri dışındaki Some değerleri için işlevimizi yaptık.

Option içerisinde Match yapısı none var olmadan çalışmayacaktır. Rust dilinde her olasılık teker teker kontrol edilmelidir. Bu nedenle null da bir olasılıktır ve kontrol edilmelidir.

Her olasılığın kapsanması gerektiği söyledik ancak bazı durumlarda tüm olasılıkları düşünemeyiz. Her nasıl if yapısındaki tüm olasılıklar gerçekleşmeyince else devreye giriyorsa bizim de match yapısı için benzer bir yapıya ihtiyacımız vardır.

Bu yapıyı göstermek için öncesinde tanıttığımız evcil_hayvan enum'una benzer bir şekilde içerisindeki değerlerin her biri için farklı birşey yazdıran kod yazabiliriz.

fn hangi_hayvan (girdi: &str){
match girdi {
"Kopek" => println!("Köpeğin var la!"),
"Kedi" => println!("Kedin var la!"),
"Balık" => println!("Balığın var la!")
}
}

Fonksiyonlarımızı oluşturduk ancak girdi olarak bu üç kavram dışında bir şey girdiğimizde match yapısının ne göstermesi gerektiğini de eklememiz lazım yoksa kodumuz çalışmaz. Bu işlemi yapmak için match yapısındaki okun sol tarafına _ şeklinde alt çizgi koymamız gerekmektedir. Bu yapı üstte belirten tüm durumların gerçekleşmemesi sonucunda çalışacaktır.

fn hangi_hayvan (girdi: &str){
match girdi {
"Kopek" => println!("Köpeğin var la!"),
"Kedi" => println!("Kedin var la!"),
"Balık" => println!("Balığın var la!"),
_ => println!("O ne la hiç duymamışam bele bişi")
}
}

Şimdi her birini çalıştırmayı denersek şu şekilde sonuçlar ile karşılaşacağız:

hangi_hayvan("Kopek"); //Köpeğin var la!
hangi_hayvan("Kedi"); //Kedin var la!
hangi_hayvan("Balık"); // Balığın var la!
hangi_hayvan("yılan"); // O ne la hiç duymamışam bele bişi

Diğer Match Yapıları

Match yapısı içerisinde birçok özellik ile gelmektedir. Bu başlıkta bu özellikleri inceleyeceğiz.

let x = 1;

match x {
1 | 2 => println!("Bir veya iki"),
_ => println!("Ne bir ne iki")

}

Yukarıda bir OR yani VEYA yapısı ifade edilmiştir. Bu yapı ile birden çok değere aynı karşılığın gelmesini sağlayabiliriz.

Bununla beraber bir aralığın tek değer döndermesini de sağlayabiliriz:

let x = 4;

match x {
1..=5 => println!("Eşleşti"),
_ => println!("Eşleşmedi")
}

Aynı zamanda match yapısına değerini de bağlamamız mümkündür.

let x = Some(5);
let y = 5;

match x {
Some(10) => println!("Bu sayı 10!"),
Some(x) if x == y => println!("Matches!"),
_ => println!("Yanlış!")
}